package org.cybzacg.convert.converters.date;

import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;

import java.time.Period;

/**
 * Period转换器
 * 专门处理Period类型的转换
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(name = "PeriodConverter", priority = ConversionPriority.MEDIUM_HIGH, description = "Period类型转换器，处理各种类型到java.time.Period的转换", enabled = true, version = "4.0", author = "cybzacg.blog", supportedTypes = {
        Period.class }, tags = { "period", "time", "conversion" })
public class PeriodConverter extends AbstractIntervalConverter<Period> {

    public PeriodConverter() {
        super(ConversionPriority.MEDIUM_HIGH);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.PERIOD;
    }

    @Override
    protected Period convertFromNumber(Number source, ConversionContext context) {
        return Period.ofDays(source.intValue());
    }

    @Override
    protected Period parseIsoFormat(String str) {
        return Period.parse(str);
    }

    @Override
    protected Period parseChineseFormat(String str) {
        int years = 0, months = 0, days = 0;

        // 提取年
        if (str.contains("年")) {
            String yearStr = str.substring(0, str.indexOf("年")).replaceAll("[^0-9-]", "");
            if (!yearStr.isEmpty()) {
                years = Integer.parseInt(yearStr);
            }
        }

        // 提取月
        if (str.contains("月")) {
            int monthStart = str.contains("年") ? str.indexOf("年") + 1 : 0;
            String monthStr = str.substring(monthStart, str.indexOf("月")).replaceAll("[^0-9-]", "");
            if (!monthStr.isEmpty()) {
                months = Integer.parseInt(monthStr);
            }
        }

        // 提取天
        if (str.contains("天")) {
            int dayStart = Math.max(str.lastIndexOf("年") + 1, str.lastIndexOf("月") + 1);
            String dayStr = str.substring(dayStart, str.indexOf("天")).replaceAll("[^0-9-]", "");
            if (!dayStr.isEmpty()) {
                days = Integer.parseInt(dayStr);
            }
        }

        return Period.of(years, months, days);
    }

    @Override
    protected Period parseSimpleFormat(String str) {
        // 格式: "Y-M-D"
        if (str.contains("-")) {
            return parseDashPeriod(str);
        }

        // 格式: "Y M D"
        if (str.contains(" ")) {
            return parseSpacePeriod(str);
        }

        // 格式: "YMD" (6位数字)
        if (str.matches("\\d{6}")) {
            return parseCompactPeriod(str);
        }

        return null;
    }

    @Override
    protected Period parseNumericString(String str) {
        int days = Integer.parseInt(str);
        return Period.ofDays(days);
    }

    @Override
    protected boolean containsChineseUnits(String str) {
        return str.contains("年") || str.contains("月") || str.contains("天");
    }

    @Override
    protected boolean isIntervalType(Object obj) {
        return obj instanceof Period;
    }

    @Override
    protected Period castToInterval(Object obj) {
        return (Period) obj;
    }

    @Override
    protected Period getDefaultValue() {
        return org.cybzacg.convert.constants.DateTimeDefaults.PERIOD_DEFAULT;
    }

    @Override
    protected String getIntervalTypeName() {
        return "Period";
    }

    /**
     * 解析横线分隔格式的时间段
     */
    private Period parseDashPeriod(String str) {
        String[] parts = str.split("-");
        int years = 0, months = 0, days = 0;

        if (parts.length >= 1) {
            years = Integer.parseInt(parts[0].trim());
        }
        if (parts.length >= 2) {
            months = Integer.parseInt(parts[1].trim());
        }
        if (parts.length >= 3) {
            days = Integer.parseInt(parts[2].trim());
        }

        return Period.of(years, months, days);
    }

    /**
     * 解析空格分隔格式的时间段
     */
    private Period parseSpacePeriod(String str) {
        String[] parts = str.trim().split("\\s+");
        int years = 0, months = 0, days = 0;

        if (parts.length >= 1) {
            years = Integer.parseInt(parts[0]);
        }
        if (parts.length >= 2) {
            months = Integer.parseInt(parts[1]);
        }
        if (parts.length >= 3) {
            days = Integer.parseInt(parts[2]);
        }

        return Period.of(years, months, days);
    }

    /**
     * 解析紧凑格式的时间段 (YMD)
     */
    private Period parseCompactPeriod(String str) {
        int years = Integer.parseInt(str.substring(0, 2));
        int months = Integer.parseInt(str.substring(2, 4));
        int days = Integer.parseInt(str.substring(4, 6));
        return Period.of(years, months, days);
    }

    @Override
    public boolean supports(Class<?> targetType) {
        return targetType == Period.class;
    }

    @Override
    public Class<?> getSupportedType() {
        return Period.class;
    }

    @Override
    public String getName() {
        return "PeriodConverter";
    }
}
